import Util from './Util';
import Constant, { ShareParam, FilePrefix } from '@/constant/Constants';
import LoggerUtil from './LoggerUtil';
import QiniuService from '@/service/QiniuService';
import type { CacheKeys } from '@/constant/CacheKeys';
import type { CustField } from '@/constant/CustField';
import { UserInfo } from '@/model/UserInfo';

export default class UniUtil {
    static key_prefix = Constant.appId + ":";
    static showSuccess(options?: UniApp.ShowToastOptions): void {
        if (Util.isEmpty(options)) {
            options = { title: "成功" };
        }
        options.image = "/static/image/done.png";
        uni.showToast(options);
    }

    static showError(options: UniApp.ShowToastOptions): void {
        options.image = "/static/image/error.png";
        uni.showToast(options);
    }

    static showWarn(options: UniApp.ShowModalOptions): void {
        uni.showModal(options);
    }

    static showToast(options: UniApp.ShowToastOptions) {
        uni.showModal(options);
    }
    static showLoading() {
        uni.showLoading({
            title: '加载中...',
            mask: true
        });
    }
    static hideLoading() {
        uni.hideLoading();
    }

    static navigateBack() {
        let options: UniApp.NavigateBackOptions = {
            "animationType": 'slide-out-bottom'
        }
        uni.navigateBack(options)
    }

    static navigateTo(path: string, success?: any, complete?: any) {
        let hasParam = path.indexOf("?") >= 0;
        uni.navigateTo({ url: path + (hasParam ? "&" : "?") + "keywords=" + Constant.seo_keywords_all, success: success, complete: complete });
    }

    static getStorage<T>(suffix: CacheKeys, type?: (new () => T)): T {
        let key = UniUtil.key_prefix + suffix.toString();
        let val = uni.getStorageSync(key);
        if (Util.isEmpty(val)) {
            return val;
        }
        if (UniUtil.isExpired(key)) {
            return <any>null;
        }

        if (null == type) {
            return val;
        } else {
            return Object.assign(<any>new type(), val);
        }
    }

    static getStorageList<T>(suffix: CacheKeys, type: (new () => T)): Array<T> {
        let key = UniUtil.key_prefix + suffix.toString();
        let vals = uni.getStorageSync(key);
        if (Util.isEmpty(vals)) {
            return vals;
        }
        if (UniUtil.isExpired(key)) {
            return <any>null;
        }
        if (null == type) {
            return vals;
        }
        let array = new Array<T>();
        vals.forEach((item: any) => {
            array.push(Object.assign(<any>new type(), item))
        });
        return array;
    }

    static setStorage<T>(suffix: CacheKeys, val: T, seconds: number = 0): void {
        let key = UniUtil.key_prefix + suffix.toString();
        uni.setStorageSync(key, val)
        UniUtil.setExpire(seconds, key);
    }

    private static setExpire<T>(seconds: number, key: string) {
        if (seconds > 0) {
            let timestamp = new Date().getTime() / 1000 + seconds;
            let expireKey = UniUtil.getExpireKey(key);
            uni.setStorageSync(expireKey, timestamp);
        }
    }

    private static getExpireKey(key: string) {
        return key + ":expire-time";
    }
    private static isExpired(key: string) {
        let now = new Date().getTime() / 1000;
        let expireKey = UniUtil.getExpireKey(key)
        let cacheTime = uni.getStorageSync(expireKey)
        if (Util.isEmpty(cacheTime)) {
            return false;
        }
        let expired = cacheTime < now;
        if (expired) {
            uni.removeStorageSync(key);
            uni.removeStorageSync(expireKey);
        }
        return expired;

    }

    static removeStorage(key: CacheKeys) {
        uni.removeStorageSync(UniUtil.key_prefix + key.toString());
    }

    static setGlobalData(key: CustField, value: any) {
        (<any>getApp()).globalData[UniUtil.key_prefix + key.toString()] = value
    }
    static delGlobalData(key: CustField) {
        UniUtil.setGlobalData(key, null)
    }
    static getGlobalData(key: CustField) {
        return (<any>getApp()).globalData[UniUtil.key_prefix + key.toString()];
    }

    static showShareMenu() {
        uni.showShareMenu({
            withShareTicket: true,
            menus: ['shareAppMessage', 'shareTimeline'],
        });
    }

    static getShareInfo(shareTicket: string) {
        uni.getShareInfo({
            shareTicket: shareTicket,
            success: function (res) {
                let errMsg = res.errMsg;
                let encryptedData = res.encryptedData;
                let iv = res.iv;
            }
        });
    }

    static async onShareAppMessage(title: string, desc: string, path: string, imgUrl?: string) {
        title = Util.isEmpty(title) ? ShareParam.title : title;
        desc = Util.isEmpty(desc) ? ShareParam.desc : desc;
        let data = <any>{
            title: title,
            desc: desc,
            path: path,
        }
        if (!Util.isEmpty(imgUrl)) {
            data.imageUrl = imgUrl;
        }
        LoggerUtil.info("onShareAppMessage:{}", JSON.stringify(data));
        return data;
    }
    static async getGoodsShareImage(imgUrl: string, price: number, canvasW: number, canvasH: number): Promise<string> {
        return new Promise((resolve) => {
            uni.getImageInfo({
                src: imgUrl, // 原图路径
                success: (res) => {
                    let ctx = uni.createCanvasContext("canvas")
                    let imageW = res.width;
                    let imageH = res.height;
                    imageW = (imageH * 5) / 4
                    ctx.setFillStyle('#FFFFFF')
                    ctx.fillRect(0, 0, imageW, imageH);
                    LoggerUtil.info("cw:{} ch:{}  iw:{},ih:{}", canvasW, canvasH, imageW, imageH);
                    ctx.drawImage(res.path, 0, 0, canvasW, canvasH);

                    let img = "/static/images/share_btn.png";
                    let imgH = canvasH / 5;
                    ctx.drawImage(img, 0, canvasH - imgH, canvasW, imgH)
                    let fontOneSize = 35;
                    ctx.setFontSize(fontOneSize);
                    ctx.setFillStyle('#FFFFFF')
                    ctx.fillText('￥', 20, canvasH - imgH + (fontOneSize * 2));

                    let fontTwoSize = 45;
                    ctx.setFontSize(fontTwoSize);
                    ctx.setFillStyle('#FFFFFF')
                    ctx.fillText(price + "", 50, canvasH - imgH + (fontTwoSize * 1.6));

                    ctx.draw(false, () => {
                        uni.canvasToTempFilePath({
                            width: canvasW,
                            height: canvasH,
                            destWidth: 750, // 标准的iphone6尺寸的两倍，生成高清图
                            destHeight: 600,
                            canvasId: "canvas",
                            fileType: "jpg",  // 注意jpg默认背景为透明
                            success: (res) => {
                                // 设置分享图片路径
                                resolve(res.tempFilePath)
                            },
                        })
                    })
                }
            })
        })
    }

    static drawImage(ctx: any, img: any, canvasW: number, canvasH: number) {
        let w = 294
        let h = 55
        let dw = canvasW / w          //canvas与图片的宽高比
        let dh = canvasH / h
        // 裁剪图片中间部分
        if (w > canvasW && h > canvasH || w < canvasW && h < canvasH) {
            if (dw > dh) {
                ctx.drawImage(img, 0, (h - canvasH / dw) / 2, w, canvasH / dw, 0, 0, canvasW, canvasH)
            } else {
                ctx.drawImage(img, (w - canvasW / dh) / 2, 0, canvasW / dh, h, 0, 0, canvasW, canvasH)
            }
        }
        // 拉伸图片
        else {
            if (w < canvasW) {
                ctx.drawImage(img, 0, (h - canvasH / dw) / 2, w, canvasH, 0, 0, canvasW, 100)
            } else {
                ctx.drawImage(img, (w - canvasW / dh) / 2, 0, canvasW / dh, h, 0, 0, canvasW, canvasH)
            }
        }
    }

    static upload(imgPath: string, key: string, token: string, success?: Function) {
        uni.uploadFile({
            url: 'https://up-z1.qiniup.com',    //此处为华北地区，其他地区请查阅文档
            name: 'file',
            filePath: imgPath,
            header: {
                "Content-Type": "multipart/form-data"
            },
            formData: {
                token: token,
                key: key
            },
            success: function (res) {
                UniUtil.showSuccess({ title: "上传成功" });
                if (null != success)
                    success();

            },
            fail: function (res) {
                LoggerUtil.info("fail:{}", JSON.stringify(res));
                UniUtil.showError({ title: "上传失败" });
            }
        });
    }

    static copy(options: { text: string, success?: any }) {
        uni.setClipboardData({
            data: options.text,
            success: options.success
        });
    }

    static getImageInfo(url: string): Promise<string> {
        return new Promise((req, rej) => {
            uni.getImageInfo({
                src: url,
                success: (res) => {
                    req(res.path)
                }
            })
        })
    }

    static canvasToImage(canvasId: string, width: number, height: number): Promise<string> {
        return new Promise((req, rej) => {
            uni.canvasToTempFilePath({
                x: 0,
                y: 0,
                width: width,
                height: height,
                destWidth: width,  //2倍关系
                destHeight: height, //2倍关系
                canvasId: canvasId,
                success: function (res) {
                    LoggerUtil.info("xxxxxxxxxxxxxxxcanvasToImage success");
                    req(res.tempFilePath);
                },
                fail: function (res) {
                    LoggerUtil.info("xxxxxxxxxxxxxxxcanvasToImage fail{}", res.errMsg);
                }
            })
        });
    }

    static singleUploadImage(key_prefix: string): Promise<string> {
        return new Promise((req, rej) => {
            uni.chooseImage({
                count: 1, //默认9
                sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
                sourceType: ['album', 'camera'], //从相册选择
                success: (res) => {
                    let url = (<[]>res.tempFilePaths).pop();
                    let key = key_prefix + new Date().getTime() + '.png';
                    QiniuService.upload(url, key, function () {
                        req(key);
                    });
                }
            });
        });
    }


    public static createVideoAd(options: VideoAdOptions) {
        let videoAd = uni.createRewardedVideoAd({
            adUnitId: options.id
        })

        videoAd.load().catch(err => LoggerUtil.info(err.errMsg));
        videoAd.onError(err => LoggerUtil.info(err.errMsg));
        videoAd.onClose(res => {
            console.log(res)
            if (res && res.isEnded) {
                options.success();
            }
            else {
                // if (options.fail != null) {
                //     options.fail();
                // } else {
                //     UniUtil.showWarn({ title: "观看完整视频才能获得奖励哦" });
                // }
            }
        })
        return videoAd;
    }


    public static showWxQrocde(wxQrcode: string) {
        uni.previewImage({
            current: wxQrcode,
            indicator: 'default',
            urls: [wxQrcode],
            longPressActions:
            {
                itemList: ['发给朋友'],
                success: function (data) {
                },
                fail: function (err) {
                }
            },
            complete: function () {
                //that.showQrcodeModal = false;
            }
        });
    }

    public static doLogin(): Promise<UserInfo.User> {
        let promise = new Promise<UserInfo.User>(resolve => {
            let option = <UniApp.LoginOptions>UniUtil.newOption(function (data: any) {
                var userInfo = data.userInfo;
                let model = Object.assign(new UserInfo.User(), userInfo);
                resolve(model);
            });
            uni.login(option);
        });
        return promise;
    }

    public static doDyLogin(): Promise<UserInfo.DyUser> {
        let promise = new Promise<UserInfo.DyUser>(resolve => {
            let option = <UniNamespace.GetUserProfileOptions>UniUtil.newOption(function (data: any) {
                var userInfo = data.userInfo;
                let model = Object.assign(new UserInfo.DyUser(), userInfo);
                resolve(model);
            });
            option.lang = "zh_CN";
            option.desc = '用于完善会员资料';
            option.withCredentials = true;
            uni.getUserProfile(option);
        });
        return promise;
    }

    public static auth(): Promise<string> {
        let promise = new Promise<string>(resolve => {
            let option = <UniApp.LoginOptions>UniUtil.newOption(function (data: any) {
                resolve(data.code);
            });
            uni.login(option)
        });
        return promise;
    }
    public static newOption(success: Function) {
        let option = {
            desc: "登录",
            provider: "weixin",
            lang: "zh_CN",
            withCredentials: true,
            success: function (data) {
                success(data);
            },
            fail: function (e) {
                LoggerUtil.info("eeee:{}", JSON.stringify(e));
                UniUtil.showError({ title: "登录失败" });
            }
        };
        return option;
    }

    public static getUserInfo() {
        uni.getUserInfo({});
    }

    public static payment(data: any): Promise<any> {
        let promise = new Promise<any>(resolve => {
            uni.requestPayment({
                provider: 'wxpay',
                timeStamp: data.timeStamp,
                nonceStr: data.nonceStr,
                package: data.package,
                signType: data.signType,
                paySign: data.sign,
                success: function (res) {
                    UniUtil.showSuccess({ title: "支付成功" });
                    resolve(null);
                },
                fail: function (err) {
                    if (err.errMsg == PayResult.cancel) {
                        resolve(err.errMsg);
                        return;
                    }
                    UniUtil.showError({ title: "支付失败" });
                    resolve(err.errMsg);
                }
            });
        });
        return promise;
    }

    public static downloadFile(url: string) {
        UniUtil.showLoading()
        uni.downloadFile({
            url: url,
            success: function (res) {
                UniUtil.hideLoading();
                uni.saveImageToPhotosAlbum({
                    filePath: res.tempFilePath, success: function (res) {
                    }, fail: function (res) {
                    }
                });
            },
            fail: function (res) {
                UniUtil.hideLoading();
            }
        });
    }

}

export class VideoAdOptions {
    id: string;
    data?: string | AnyObject | ArrayBuffer;
    success: () => void;
    fail: () => void;
}



